<?php

function trace($description, $information, $active=true){
	if ($active && TRACE){
		$time = date('i:s');
		$web = ini_get('display_errors');
		if ($web)
			echo '<hr/>'.$time.' - <strong>'.$description.':</strong><br/><pre>'.$information.'</pre><hr/>';
		else {
			$message = "\n".$time." - [$description]: $information";
			error_log($message, 3, TRACELOG);
		}
	}
}

function assert_handler($file, $line, $code){
	//TODO log error in log file when assertion fails
	echo "
		<hr>Assertion Failed<br/>
		<u><b>File:</u></b> $file<br />
		<u><b>Line:</u></b> $line<br />
		<u><b>Code:</u></b> $code<br /><hr />";
}

function array_print($array, $prefix=''){
	if (ini_get('display_errors'))
		$break = '<br/>';
	else
		$break = "\n";
	$out = "array:$break";
	foreach($array as $key => $value){
		$text = is_array($value) ? array_print($value, $prefix.'    ') : $value;
		if($prefix) $out.=$prefix.$key.'->'.$text.$break; //PEAK
	}
	return $out;
}

function hv($thing){//"has value"
	return ( isset($thing) && (''!=$thing) );
}

function get_metavalues($user_id){
	global $wpdb, $blog;
	$blog_metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE blog = '$blog' AND user_id = '$user_id'");
	$Lyceum_metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE meta_domain = 'system' AND user_id = '$user_id'");
//	trace('$blog_metavalues', array_print($blog_metavalues));
//	trace('$Lyceum_metavalues', array_print($Lyceum_metavalues));
	arrayify($blog_metavalues);	
	arrayify($Lyceum_metavalues);
	$metavalues = array_merge($blog_metavalues, $Lyceum_metavalues);
	return $metavalues;
}

function get_userblogs(){
	global $user_ID, $wpdb, $table_prefix;
	$blogs = $wpdb->get_results("
		SELECT DISTINCT $wpdb->blogs.id, blognametable.option_value AS blogname, bloghometable.option_value AS home, status
		FROM $wpdb->blogs
			INNER JOIN $wpdb->options AS blognametable ON ($wpdb->blogs.id = blognametable.blog)
			INNER JOIN $wpdb->options AS bloghometable ON ($wpdb->blogs.id = bloghometable.blog)
			INNER JOIN $wpdb->usermeta ON ($wpdb->blogs.id = $wpdb->usermeta.blog)
		WHERE
			status = 'active' AND
			meta_key = '{$table_prefix}capabilities' AND
			blognametable.option_name = 'blogname' AND
			bloghometable.option_name = 'home' AND
			user_id = '$user_ID'
	");
	return $blogs;
}

// Retrieves the $num last posts published on the entire system
function get_recent_posts($num){
	global $wpdb;

	$gmt_now = gmdate('Y-m-d H:i:s');

	$post_ids = $wpdb->get_col(
		"SELECT DISTINCT $wpdb->posts.ID
		FROM $wpdb->posts
			INNER JOIN $wpdb->post2cat ON (post_id = $wpdb->posts.ID)
				INNER JOIN $wpdb->categories ON (category_id = cat_ID )
					INNER JOIN $wpdb->blogs ON (blog = $wpdb->blogs.id)
		WHERE
			status = 'active' AND
			post_status = 'publish' AND
			post_password = '' AND
			post_date_gmt < '$gmt_now'
		ORDER BY post_date_gmt DESC
		LIMIT $num
	");

	$posts = array();
	foreach($post_ids as $id)
		$posts[] = get_post($id);
	return $posts;
}

function rfc3339($date){
	preg_match('/([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9])/', $date, $matches);
	return $matches[1].'T'.$matches[2].'Z';
}

//TODO: specify optiondomain?
function get_admin_option_array($optiontype){
	global $wpdb;
	return explode(',', $wpdb->get_var("SELECT `option_value` FROM `$wpdb->options` WHERE `option_name` = '$optiontype'"));	
}

function set_admin_option_array($optiontype, $newarray){
	global $wpdb;
	$value = implode(',', $newarray);
	$wpdb->query("UPDATE `$wpdb->options` SET option_value = '$value' WHERE `option_name` = '$optiontype'");	
}

function get_admin_ips() {
	return get_admin_option_array('admin_ips');
}

function add_admin_ip($newip){
	global $wpdb;
	$ips = get_admin_ips();
	$ips[]=$newip;
	$value = implode(',', $ips);
	$wpdb->query("UPDATE `$wpdb->options` SET option_value = '$value' WHERE `option_name` = 'admin_ips'");
}

function check_admin_ip(){
	global $wpdb;
	return array_search($_SERVER['REMOTE_ADDR'], get_admin_ips());
}

function comments_post_name(){
	global $wpdb;
	return $wpdb->get_var("SELECT `option_value` FROM `$wpdb->options` WHERE `option_name`='wp-comments-post_hash' AND `option_domain`='system'");
}

function delete_dir($dir) {
	if(!$dh = @opendir($dir))
		return;
	while (($obj = readdir($dh))) {
		if($obj=='.' || $obj=='..') 
			continue;
		if (!@unlink($dir.'/'.$obj)) {
			delete_dir($dir.'/'.$obj);
			} else {
				$file_deleted++;
			}
		}
		if (@rmdir($dir)) 
			$dir_deleted++;
}

function empty_dir($dir){
	if(!$dh = @opendir($dir))
		return;
	while (($obj = readdir($dh))) {
		if(in_array( $obj, array('.', '..', '.svn')))
			continue;
		if (!@unlink($dir.'/'.$obj)) {
			delete_dir($dir.'/'.$obj);
			} else {
				$file_deleted++;
			}
		}
}

function arrayify(&$thing){
	$thing = $thing ? $thing : array();
}

function bloginput(){
	global $blogdata;
	return "<input type=\"hidden\" name=\"b\" value=\"$blogdata->slug\" />";
}

function tokeninput($targetscript, $action='default', $id=0){
	$token = formtoken($targetscript, $action, $id);
	return "<input type=\"hidden\" name=\"token\" value=\"$token\" />";
}

function formtoken($targetscript, $action='default', $id=0) {
	global $userdata;
	$name = "$targetscript-$action-$id";
	arrayify($_SESSION['formtokens']);                // This could be done better -jjb
	$token = sha1(uniqid(rand(), TRUE));
	$key = sha1($targetscript.$action.$id.$userdata->ID);
	$_SESSION['formtokens'][$key][$token] = time();
//trace('generating token: $token, $targetscript, $action, $id, user, $key', "$token, $targetscript, $action, $id, $userdata->ID, $key");
	return $token;
}

function tokenIsValid ($token, $targetscript, $action='default', $id=0, $keep=false) {
	global $userdata;
//trace('$_SESSION', array_print($_SESSION));
	$key = sha1($targetscript.$action.$id.$userdata->ID);
//trace('checking token: $token, $targetscript, $action, $id, user, $key', "$token, $targetscript, $action, $id, $userdata->ID, $key");
	//if (!array_key_exists($token, $_SESSION['formtokens'][$key]))
	//	return false;

	$token_age = time() - $_SESSION['formtokens'][$key][$token];

	if ($token_age >= 86400 and $_SESSION['formtokens'][$key][$token])//86400 seconds = 24 hours
		return false;

	if (!$keep)
		unset($_SESSION['formtokens'][$key][$token]);
	return true;
}

function validateToken( $token, $targetscript, $action='default', $id=0, $keep=false ){
	if (!tokenIsValid( $token, $targetscript, $action, $id, $keep ))
		badTokenMessage();
}

function badTokenMessage(){
	die("Your tokens have timed out. <a href='{$_SERVER['HTTP_REFERER']}'>Reload</a> the page to reset your tokens. (this link might not take you anywhere useful.). The contents of your request is printed below-- It has not been saved to the system! You should save this if it does not exist elsewhere!<pre>". array_print($_REQUEST) . '</pre>');
}

function formOpenTag($attributes=''){
	global $id; 
	// $home = SUBDOMAINS ? '' : WEBROOT;
	// $cpn = comments_post_name();
	// 
	// echo "<form action='$home/$cpn' method='post' id='commentform' $attributes>";
	echo bloginput();//i think this is never needed
	echo tokeninput(comments_post_name(), 'default', $id);	
}

// returns true if slug is lowercase alphanumeric & slug isn't blacklisted
function validateSlug($slug){
	$denied = get_admin_option_array('slug_blacklist');
	$denied[] = '';

	foreach ($denied as $badslug)
		if (strcmp(strtolower($slug),$badslug) == 0)
			return false;
	if (0 != strcmp($slug,strtolower($slug)))
		return false;
	return preg_match('/^[\w_-]*$/',$slug);
}

function username_is_blacklisted($username){
	$denied = get_admin_option_array('username_blacklist');
	$denied[] = '';

	foreach ($denied as $badusername)
		if (strcmp(strtolower($username), $badusername) == 0)
			return true;
	
	return false;
}

function slug_from_postid($postid){
	global $wpdb;
	return $wpdb->get_var("
		SELECT
			slug 
			FROM $wpdb->blogs
				INNER JOIN $wpdb->categories ON (id = blog)
					INNER JOIN $wpdb->post2cat ON (category_id = cat_ID)
			WHERE
				post_id = '$postid'
			LIMIT 1
	");
}

function delete_blog($blog){
	global $wpdb;

	//  delete comments
	$wpdb->query("
		DELETE $wpdb->comments FROM $wpdb->comments
			INNER JOIN $wpdb->post2cat ON (comment_post_ID = post_id)
				INNER JOIN $wpdb->categories ON (category_id = cat_ID)
		WHERE
			blog = '$blog'
	");

	//  postmeta records
	$wpdb->query("
		DELETE $wpdb->postmeta FROM $wpdb->postmeta
			INNER JOIN $wpdb->post2cat ON ($wpdb->postmeta.post_id = $wpdb->post2cat.post_id)
				INNER JOIN $wpdb->categories ON (category_id = cat_ID)
		WHERE
			blog = '$blog'
	");

	//  postsearch
	$wpdb->query("
		DELETE $wpdb->postsearch FROM $wpdb->postsearch
			INNER JOIN $wpdb->post2cat ON ($wpdb->postsearch.post_id = $wpdb->post2cat.post_id)
				INNER JOIN $wpdb->categories ON (category_id = cat_ID)
		WHERE
			blog = '$blog'
	");

	//  posts
	$wpdb->query("
		DELETE $wpdb->posts FROM $wpdb->posts
			INNER JOIN $wpdb->post2cat ON (post_id = ID)
				INNER JOIN $wpdb->categories ON (category_id = cat_ID)
		WHERE
			blog = '$blog'
	");

	//  category<->post join records
	$wpdb->query("
		DELETE from $wpdb->post2cat USING $wpdb->post2cat
			INNER JOIN $wpdb->categories ON (category_id = cat_ID)
		WHERE
			blog = '$blog'
	");

	//  categories
	$wpdb->query("
		DELETE from $wpdb->categories
		WHERE blog = '$blog'
	");
	
	//  options
	$wpdb->query("
		DELETE from $wpdb->options
		WHERE
			blog = '$blog' AND
			option_domain = 'blog'
	");

	//  links
	$wpdb->query("
	DELETE from $wpdb->links USING $wpdb->links
		INNER JOIN $wpdb->linkcategories ON (cat_id = link_category)
	WHERE
		blog = '$blog'
	");

	//  link categories
	$wpdb->query("
		DELETE from $wpdb->linkcategories
		WHERE blog = '$blog'
	");

	//  usermeta
	$wpdb->query("
		DELETE FROM $wpdb->usermeta WHERE blog = '$blog'
	");

	// blog record
	$wpdb->query("
		DELETE FROM $wpdb->blogs WHERE id = '$blog'
	");	
}

function delete_user($username){
	global $wpdb;

	$user = $wpdb->get_var("SELECT ID from $wpdb->users WHERE user_login = '$username'");

	//  comments
	$wpdb->query("
		DELETE FROM $wpdb->comments WHERE user_id = '$user'
	");
	
	//  posts and pages
	$wpdb->query("
		DELETE FROM $wpdb->posts WHERE post_author = '$user'
	");

	//  usermeta
	$wpdb->query("
		DELETE FROM $wpdb->usermeta WHERE user_id = '$user'
	");

	//  user
	$wpdb->query("
		DELETE FROM $wpdb->users WHERE ID = '$user'
	");
}

function lyceum_404(){
	header("HTTP/1.1 404 Not Found");
}

function remove_token_arg($url){
	return preg_replace('/&?token=[^&]+/', '', $url);
}

function get_url_arg_pairs($url) {
	$parsed_url = parse_url($url);
	$args = $parsed_url['query'];
	$arr  = array();	
	foreach (explode('&', $args) as $i) {
		list($name,$value) = explode('=', $i, 2);
		$arr[$name] = $value;
	}	
	return $arr;
}

?>
